// PGLDataTypes.h: interface for the CPGLDataTypes class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_PGLDATATYPES_H__92968E23_E28C_4574_94E3_89CB59FF3F2E__INCLUDED_)
#define AFX_PGLDATATYPES_H__92968E23_E28C_4574_94E3_89CB59FF3F2E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <pgl/core/PGLData.h>

/*! \brief A linearly spaced vector

	This class defines linearly spaced vector characterized by:

	- an origin \f$x_0\f$,
	- a step \f$dx\f$,
	- and a number of steps.

  As expected, the mathematical equation underneath this class is extremely simple:
  \f[ f(i) = x_0 + i dx \ . \f]

  \ingroup PGLDataSpecialGroup
*/
class PGLCORE_EXT_CLASS CPGLLinearVector : public CPGLData
{
PGL_DECLARE_DATA_TYPE( CPGLLinearVector, CPGLData, true, true );
public:
	//! \name Constructors
	//@{
	//! Default constructor
	CPGLLinearVector( float fOrigin = 0, float fStep = 1, size_t uNSteps = 10 );
	//! Copy constructor
	CPGLLinearVector( const CPGLLinearVector& lv)	{ *this = lv;};
	//! Assignement constructor
	CPGLLinearVector& operator = (const CPGLLinearVector& lv);
	~CPGLLinearVector(){};
	//@}

	//! \name Virtual overrides
	//@{
	//! returns the size of the vector
	size_t size() const								{	return m_uNSteps;};
	//! member access, cosnt
	float at(size_t i) const						{	return static_cast<float>(m_fOrigin+i*m_fStep);};
	//! see STL
	void resize(size_t n)							{   m_uNSteps=__max(0,n);};
	//! see STL
	void clear()									{   m_uNSteps=0;};
	//@}

	//! \name Min, max override
	//@{
	//! returns 0
	virtual size_t GetMinIndex() const								{	return 0;};
	//! returns size()-1
	virtual size_t GetMaxIndex() const								{	return m_uNSteps-1;};
	//! set uMin = 0, uMax = size()-1
	virtual void GetMinMaxIndex(size_t& uMin, size_t& uMax) const	{	uMin = 0; uMax = m_uNSteps-1;};
	//@}

	//! \name Getters and setters
	//@{
	//! returns vector origin
	float GetOrigin() const			{	return m_fOrigin;};
	//! returns vector step
	float GetStep() const			{	return m_fStep;};
	//! sets vector origin equal to fOrigin
	void SetOrigin(float fOrigin)	{	m_fOrigin = fOrigin;};
	//! sets vector step equal to fStep
	void SetStep(float fStep)		{	m_fStep = fStep;};
	//@}

protected:
	//! Attributes
	//@{
	//! data start
	float m_fOrigin;
	//! step
	float m_fStep;
	//! number of steps
	size_t m_uNSteps;
	//@}
};

PGL_DECLARE_SMARTPTR( CPGLLinearVector )


/*!
	\defgroup PGLTempValarrayGroup Valarray, based on STL valarray.
\ingroup PGLDataGroup
*/

/*! \brief Virtual valarray template

  A classical valarray object, based on STL vector. There are several constructors and cast to transform this object
  to/from vector<>.

  \ingroup PGLTempValarrayGroup
*/
template <typename T>
class PGLCORE_EXT_CLASS CPGLValarray : public CPGLData
{
public:
	//! \name Type definition
	//@{
	typedef T value_type;
	typedef T& reference;
	//! Vector of T
	typedef std::valarray<T> ValarrayT;
	//@}

	//! \name Constructors
	//@{
	//! Default constructor
	CPGLValarray<T>()										{};
	//! Construct a vector of size n
	CPGLValarray<T>(size_t n): m_v(n)							{};
	//! Construct a vector from v
	CPGLValarray<T>(const ValarrayT& v): m_v(v)				{};
	//! Copy constructor
	CPGLValarray<T>(const CPGLValarray<T>& v)				{	*this = v;};
	//! Assignment constructor
	CPGLValarray<T>& operator = (const CPGLValarray<T>& v)	{ if (this != &v) {m_v = v.m_v;} return *this;};
	virtual ~CPGLValarray<T>()								{ m_v.free();};
	//@}

	//! \name Virtual overrides
	//@{
	//! return the size of the vector
	size_t size() const						{	return m_v.size();};
	//! see STL
	void resize(size_t n)					{   CSingleLock s(&m_mutex); s.Lock(); if (s.IsLocked()) { m_v.resize(n); s.Unlock();} };
	//! clear object
	void clear()							{	CSingleLock s(&m_mutex); s.Lock(); if (s.IsLocked()) { m_v.resize(0); s.Unlock();} };
	//! index accessor
	float operator [](size_t i)	const		{   return at(i);};
	//! access operator, const
	float at(size_t i) const				{   ASSERT(i<m_v.size()); return static_cast<float>(m_v[i]);};
	//@}

	//! \name STL vector access and manipulation
	//@{
	//! setting the vector content
	void SetV(const ValarrayT& v)		{	m_v=v;};
	//! return the STL vector 
	ValarrayT& GetV()					{	return m_v;};
	//! returns the STL vector, const
	const ValarrayT& GetV() const 		{	return m_v;};
	//! access operator, reference
	reference operator [](size_t i)			{   return at(i);};
	//! access operator, reference
	reference at(size_t i)						{   ASSERT(i<m_v.size()); return m_v[i];};
	//@}
	

protected:
	//! \name Attributes
	//@{
	//! STL vector.
	ValarrayT m_v;
	//@}
};



#ifndef PGL_DECLARE_VALARRAY_DATA_TYPE
	#define PGL_DECLARE_VALARRAY_DATA_TYPE( className , classType)\
	class PGLCORE_EXT_CLASS className : public CPGLValarray< classType > \
	{ \
	PGL_DECLARE_DATA_TYPE( className, CPGLValarray< classType >, true, true ); \
	public: \
		className () {}; \
		className (size_t n) : CPGLValarray< classType > (n){}; \
		className (const ValarrayT& v) : CPGLValarray< classType > (v) {}; \
		className (const className & v)					{	*this = v;}; \
		className & operator = (const className & v)	{	if (this != &v) { this->CPGLValarray< classType >::operator =(v); } return *this;}; \
	};\
	PGL_DECLARE_SMARTPTR( className )
#endif

/*! \class CPGLValarrayD
	\brief A Valarray of double
	\sa CPGLValarray
  \ingroup PGLTempValarrayGroup
*/
/*! \class CPGLValarrayF
	\brief A Valarray of float
	\sa CPGLValarray
  \ingroup PGLTempValarrayGroup
*/
/*! \class CPGLValarrayI
	\brief A Valarray of int
	\sa CPGLValarray
  \ingroup PGLTempValarrayGroup
*/
/*! \class CPGLValarrayB
	\brief A Valarray of BYTE
	\sa CPGLValarray
  \ingroup PGLTempValarrayGroup
*/
/*! \class CPGLValarrayS
	\brief A Valarray of short
	\sa CPGLValarray
  \ingroup PGLTempValarrayGroup
*/
/*! \class CPGLValarrayL
	\brief A Valarray of long
	\sa CPGLValarray
  \ingroup PGLTempValarrayGroup
*/

PGL_DECLARE_VALARRAY_DATA_TYPE(CPGLValarrayD, double)
PGL_DECLARE_VALARRAY_DATA_TYPE(CPGLValarrayF, float)
PGL_DECLARE_VALARRAY_DATA_TYPE(CPGLValarrayB, BYTE)
PGL_DECLARE_VALARRAY_DATA_TYPE(CPGLValarrayI, int)
PGL_DECLARE_VALARRAY_DATA_TYPE(CPGLValarrayS, short)
PGL_DECLARE_VALARRAY_DATA_TYPE(CPGLValarrayL, long)


/*!
	\defgroup PGLTempValarrayRefGroup Valarray, based on a reference to STL vector.
\ingroup PGLDataGroup
*/

/*! \brief A reference to a Valarray template

	This object stores a reference to an existing Valarray. No manipulation is made on this Valarray (declared as const).
\par Serialization

The object cannot serialize the reference, hence it is serialized as a CPGLValarray<T>.

  \ingroup PGLTempValarrayRefGroup
*/
template <typename T>
class PGLCORE_EXT_CLASS CPGLValarrayRef : public CPGLData
{
public:
	//! \name Type definition
	//@{
	typedef T value_type;
	typedef T& reference;
	//! Valarray of T
	typedef std::valarray<T> ValarrayT;
	//@}

	//! \name Constructors
	//@{
	//! Default constructor
	CPGLValarrayRef<T>():m_pV(NULL){};
	//! Construct from reference to v, v must be valid
	CPGLValarrayRef<T>(const ValarrayT& v) : m_pV(&v){};
	//! Construct from handle pV, pV must be valid
	CPGLValarrayRef<T>(const ValarrayT* pV): m_pV(pV){};
	//! Copy constructor
	CPGLValarrayRef<T>(const CPGLValarrayRef<T>& v):m_pV(NULL)	{	*this = v;};
	//! Assignement constructor
	CPGLValarrayRef<T>& operator = (const CPGLValarrayRef<T>& v){	if (this != &v) { m_pV = v.m_pV;} return *this;};
	virtual ~CPGLValarrayRef<T>() {};
	//@}

	//! \name Virtual overrides
	//@{
	//! returns the size of the Valarray
	size_t size() const						{	if(!m_pV)return 0; return m_pV->size();};
	//! index accessor
	float operator[] (size_t i) const		{	return at(i);};
	//! access operator, const
	float at(size_t i) const				{	ASSERT(m_pV); ASSERT(i<m_pV->size()); return static_cast<float>((*m_pV)[i]);};
	//! clear
	void clear()							{	m_pV=NULL;};
	//@}

	//! \name Valarray manipulation
	//@{
	//! Setting the reference
	void SetV(const ValarrayT& v)		{	m_pV=&v;};
	//! returns the reference Valarray
	const ValarrayT& GetV() const		{	ASSERT(m_pV); return *m_pV;};
	//@}
	
protected:
	//! \name Attributes
	//@{
	//! pointer to Valarray
	const ValarrayT* m_pV;
	//@}
};

#define PGL_DECLARE_VALARRAYREF_DATA_TYPE( className , classType) \
class PGLCORE_EXT_CLASS className : public CPGLValarrayRef< classType > \
{ \
PGL_DECLARE_DATA_TYPE( className, CPGLValarrayRef< classType >,false, true); \
public: \
	className () {}; \
	className (const ValarrayT& v) : CPGLValarrayRef< classType > (v){}; \
	className (const ValarrayT* pV) : CPGLValarrayRef< classType > (pV) {}; \
	className (const className & v)					{	*this = v;}; \
	className & operator = (const className & v) \
	{	if (this != &v) { this->CPGLValarrayRef< classType >::operator =(v); } return *this;}; \
};\
PGL_DECLARE_SMARTPTR( className );

/*! \class CPGLValarrayRefD
	\brief A reference to a Valarray of double
	\sa CPGLValarrayRef
  \ingroup PGLTempValarrayRefGroup
*/
/*! \class CPGLValarrayRefF
	\brief A reference to a Valarray of float
	\sa CPGLValarrayRef
  \ingroup PGLTempValarrayRefGroup
*/
/*! \class CPGLValarrayRefI
	\brief A reference to a Valarray of int
	\sa CPGLValarrayRef
  \ingroup PGLTempValarrayRefGroup
*/
/*! \class CPGLValarrayRefB
	\brief A reference to a Valarray of BYTE
	\sa CPGLValarrayRef
  \ingroup PGLTempValarrayRefGroup
*/
/*! \class CPGLValarrayRefS
	\brief A reference to a Valarray of short
	\sa CPGLValarrayRef
  \ingroup PGLTempValarrayRefGroup
*/
/*! \class CPGLValarrayRefL
	\brief A reference to a Valarray of long
	\sa CPGLValarrayRef
  \ingroup PGLTempValarrayRefGroup
*/

PGL_DECLARE_VALARRAYREF_DATA_TYPE( CPGLValarrayRefD, double)
PGL_DECLARE_VALARRAYREF_DATA_TYPE( CPGLValarrayRefF, float)
PGL_DECLARE_VALARRAYREF_DATA_TYPE( CPGLValarrayRefB, BYTE)
PGL_DECLARE_VALARRAYREF_DATA_TYPE( CPGLValarrayRefI, int)
PGL_DECLARE_VALARRAYREF_DATA_TYPE( CPGLValarrayRefS, short)
PGL_DECLARE_VALARRAYREF_DATA_TYPE( CPGLValarrayRefL, long)

/*!
	\defgroup PGLTempCircVectorGroup Circular Vectors, based on a reference to STL vector.
\ingroup PGLDataGroup
*/

/*! \brief Virtual circular vector template

  A circular vector.

  \image html circvector.png "Circular vector scheme"
  \ingroup PGLTempCircVectorGroup
*/
template <typename T>
class PGLCORE_EXT_CLASS CPGLCircVector : public CPGLData
{
public:
	//! \name Type definition
	//@{
	typedef T value_type;
	typedef T& reference;
	//! Vector of T
	typedef std::vector<T> VectorT;
	//@}

	//! \name Constructors
	//@{
	//! Default constructor
	CPGLCircVector<T>()	: m_uStart(0)								
    {};
	//! Construct a vector of size n
	CPGLCircVector<T>(size_t n): m_v(n), m_uStart(0)					
    {};
	//! Construct a vector from v
	CPGLCircVector<T>(const VectorT& v): m_v(v), m_uStart(0)	
    {};
	//! Copy constructor
	CPGLCircVector<T>(const CPGLCircVector<T>& v)				
    {	*this = v;};
	//! CircAssignment constructor
	CPGLCircVector<T>& operator = (const CPGLCircVector<T>& v)	
    {	if (this != &v) {m_v = v.m_v; m_uStart = v.m_uStart;} return *this;};
	//@}

	//! \name Virtual overrides
	//@{
	//! return the size of the vector
	size_t size() const						{	return m_v.size();};
	//! access operator, reference
	float operator[] (size_t i) const		{   return at(i);};
	//! access operator, reference
	float at(size_t i) const				{   ASSERT(i<m_v.size()); return static_cast<float>(m_v[(m_uStart+i)%(m_v.size()-1)]);};
	//! see STL
	void resize(size_t n)					{	CSingleLock s(&m_mutex); s.Lock(); if (s.IsLocked()) { m_v.resize(n); s.Unlock();} };
	//! see STL
	void clear()							{	CSingleLock s(&m_mutex); s.Lock(); if (s.IsLocked()) { m_v.clear(); s.Unlock();} };
	//@}

	//! \name STL vector access and manipulation
	//@{
	//! setting the vector content
	void SetV(const VectorT& v)	{	m_v=v;};
	//! return the STL vector 
	VectorT& GetV()				{	return m_v;};
	//! returns the STL vector, const
	const VectorT& GetV() const	{	return m_v;};
	//! access operator, reference
	reference operator [](size_t i)					{   ASSERT(i<m_v.size()); return at(i);};
	//! access operator, reference
	reference at(size_t i)							{   ASSERT(i<m_v.size()); return m_v[(m_uStart+i)%(m_v.size()-1)];};
	//@}

	//! Circular vector specific
	//@{
	//! return first virtual index
	size_t GetStart() const			{	return m_uStart;};
	//! increment virtual index of i, default is 1
	void StepStart()				{	m_uStart++; m_uStart%=m_v.size()-1;};
	//! increment virtual index of i, default is 1
	void SetStart(size_t i = 1)		{	m_uStart += i; m_uStart%=m_v.size()-1;};
	//@}

protected:
	//! \name Attributes
	//@{
	//! STL vector.
	VectorT m_v;
	//! Start index
	size_t m_uStart;
	//@}
};

#define PGL_DECLARE_CIRCVECTOR_DATA_TYPE( className , classType)\
class PGLCORE_EXT_CLASS className : public CPGLCircVector< classType > \
{ \
PGL_DECLARE_DATA_TYPE( className, CPGLCircVector< classType >, true, true ); \
public: \
	className () {}; \
	className (size_t n) : CPGLCircVector< classType > (n){}; \
	className (const VectorT& v) : CPGLCircVector< classType > (v) {}; \
	className (const className & v)					{	*this = v;}; \
	className & operator = (const className & v)\
    {	if (this != &v) { this->CPGLCircVector< classType >::operator =(v); } return *this;}; \
};\
PGL_DECLARE_SMARTPTR( className )

/*! \class CPGLCircVectorD
	\brief A circular vector of double
	\sa CPGLCircVector
  \ingroup PGLTempCircVectorGroup
*/
/*! \class CPGLCircVectorF
	\brief A circular vector of float
	\sa CPGLCircVector
  \ingroup PGLTempCircVectorGroup
*/
/*! \class CPGLCircVectorI
	\brief A circular vector of int
	\sa CPGLCircVector
  \ingroup PGLTempCircVectorGroup
*/
/*! \class CPGLCircVectorB
	\brief A circular vector of BYTE
	\sa CPGLCircVector
  \ingroup PGLTempCircVectorGroup
*/
/*! \class CPGLCircVectorS
	\brief A circular vector of short
	\sa CPGLCircVector
  \ingroup PGLTempCircVectorGroup
*/
/*! \class CPGLCircVectorL
	\brief A circular vector of long
	\sa CPGLCircVector
  \ingroup PGLTempCircVectorGroup
*/

PGL_DECLARE_CIRCVECTOR_DATA_TYPE(CPGLCircVectorD, double)
PGL_DECLARE_CIRCVECTOR_DATA_TYPE(CPGLCircVectorF, float)
PGL_DECLARE_CIRCVECTOR_DATA_TYPE(CPGLCircVectorB, BYTE)
PGL_DECLARE_CIRCVECTOR_DATA_TYPE(CPGLCircVectorI, int)
PGL_DECLARE_CIRCVECTOR_DATA_TYPE(CPGLCircVectorS, short)
PGL_DECLARE_CIRCVECTOR_DATA_TYPE(CPGLCircVectorL, long)

/*! \example data.cpp
Manipulating the data engine.
*/

/*!
	\defgroup PGLDataSpecialGroup Specialized vectors and containers
\ingroup PGLDataGroup
*/


/*! \brief A PGLData modifier based on a function

This classes uses a user provided function to modify any PGLData object:


  \ingroup PGLDataSpecialGroup
*/
class PGLCORE_EXT_CLASS CPGLFcnData : public CPGLData
{
PGL_DECLARE_DATA_TYPE( CPGLFcnData, CPGLData, false, true );
public:
	typedef std::unary_function< float, float > Callback;
	typedef boost::shared_ptr< Callback > CallbackPtr;
	//! \name Constructors
	//@{
	//! Default constructor
	CPGLFcnData(): m_pData(CPGLDataPtr()), m_pFcn(CallbackPtr()){};
	//! Classic constructor
	CPGLFcnData( Callback const& pFcn, CPGLDataPtr pData) : m_pFcn(new Callback(pFcn)), m_pData(pData){};
	//! Copy constructor
	CPGLFcnData( const CPGLFcnData& fcn):m_pData(CPGLDataPtr()), m_pFcn(m_pFcn)	{};
	//! Assignement constructor
	CPGLFcnData& operator = (const CPGLFcnData& lv);
	//@}

	//! \name Virtual overrides
	//@{
	//! returns the size of the vector
	size_t size() const								{	if(!m_pData) return 0;  return m_pData->size();};
	//! member access, cosnt
	float at(size_t i) const						
	{	
		ASSERT(m_pData.get()); 
		ASSERT(m_pFcn.get()); 
//		return static_cast<float>(  m_pFcn->operator()(  m_pData->at(i) )  );
		return 0;
	};
	//! see STL
	void clear()									{   if(m_pData)  m_pData->clear();};
	//! return f(x)
	void GetFx(std::vector<float>& v);
	//@}

protected:
	//! Attributes
	//@{
	//! data object
	CPGLDataPtr m_pData;
	//! function
	CallbackPtr m_pFcn;
	//@}
};

PGL_DECLARE_SMARTPTR( CPGLFcnData )

/*! \brief A PGLData modifier based on a parsed mathematical function

This object transforms a CPGLData object by a user-defined mathematical function.

\par Example of use
\code
//! Creating a linear vector
CPGLLinearVector* pLinVector = new CPGLLinearVector( 0, 1, 10);
//! Creating an object on the heap
CPGLMathFcnData* pMathData = new CPGLMathFcnData( pLinVector );
//! parsing function
if (pMathData->Parse(_T("sin(x^2)+pow(x,2)*cos(x/2.0)"), _T("x")) > 0)
{
	// couldn't parse the function...
	TRACE( _T("Math function parsing failed, %s"), pMathData->GetParseErrorMsg() );
	...
}

// the object is ready to use.
\endcode

  \ingroup PGLDataSpecialGroup
*/
class PGLCORE_EXT_CLASS CPGLMathFcnData : public CPGLData
{
PGL_DECLARE_DATA_TYPE( CPGLMathFcnData, CPGLData, true, true );
public:
	//! \name Constructors
	//@{
	//! Default constructor
	CPGLMathFcnData(){};
	//! Classic constructor
	CPGLMathFcnData(CPGLDataPtr pData):m_pData(pData){};
	//! Copy constructor
	CPGLMathFcnData( const CPGLMathFcnData& fcn):m_pData(CPGLDataPtr())	{ *this = fcn;};
	//! Assignement constructor
	CPGLMathFcnData& operator = (const CPGLMathFcnData& lv);
	~CPGLMathFcnData(){ m_pData.reset();};
	//@}

	//! \name Virtual overrides
	//@{
	//! returns the size of the vector
	size_t size() const								{	if(!m_pData) return 0;  return m_pData->size();};
	//! member access, cosnt
	float at(size_t i) const;
	//! see STL
	void clear()									{   if( m_pData.get() )  m_pData->clear();};
	//! return f(x)
	void GetFx(std::vector<float>& v);
	//@}

	//! \name Function parsing
	//@{
	/*! \brief Parse and compile the mathematical function

	\param szFunction unvariable mathematical expression
	\param szVar variable name (case sensitive)
	\return -1 if successful
	\return index of the character where an error appeard if index smaller than szFunction size
	\return error code if index greater that szFunction size

	\warning szFunction must be univariate !

	\sa fcnparser::CFunctionParser
	\sa fcnparser::Parse
	\sa fcnparser::ErrorMsg
	*/
	int Parse( LPCTSTR szFunction, LPCTSTR szVar);
	//! return the error message corresponding to the last Parse error 
	LPCTSTR GetParseErrorMsg() const;
	//@}

protected:
	//! Attributes
	//@{
	//! data object
	CPGLDataPtr m_pData;
	//! function parser
	fcnparser::CFunctionParser m_parser;
	//@}
};

PGL_DECLARE_SMARTPTR( CPGLMathFcnData )

/*! \brief A SAFEARRAY class

*/
class PGLCORE_EXT_CLASS CPGLSafeArray : public CPGLData
{
PGL_DECLARE_DATA_TYPE( CPGLSafeArray, CPGLData, false, true);
public:
	//! \name Constructors
	//@{	
	/*! \brief Create an array of n elements

	\param number of elements,
	\param vt type of variable ( VT_R4(default) or VT_R8 )
	
	  \sa AttachArraay
	*/
	CPGLSafeArray(size_t n, VARTYPE vt = VT_R4);
	/*! \brief Create object from existing safe array

	\sa AttachArray
	*/
	CPGLSafeArray( SAFEARRAY* pArray = NULL, bool bCleaning = true);
	/*! \brief Create object from existing variant

    \sa AttachArray
	*/
	CPGLSafeArray( VARIANT v, bool bCleaning = true);
	//! Copy constructor
	CPGLSafeArray( const CPGLSafeArray& sa):m_pArray(NULL)	{ *this = sa;};
	//! Assignement constructor
	CPGLSafeArray& operator = (const CPGLSafeArray& sa);
	//! Destructor
	~CPGLSafeArray();
	//@}

	//! \name Virtual overrides
	//@{
	//! returns the size of the vector
	size_t size() const;
	//! member access, cosnt
	float at(size_t i) const;
	//! see STL
	void clear()								{   CleanArray();};
	//@}

	//! \name Safe array handling
	//@{
	HRESULT GetLastHRESULT() const				{	return m_hr;};
	//! return array var type
	VARTYPE GetVarType() const					{	return m_vt;};
	//! returns the safe array
	SAFEARRAY* GetArray()						{	return m_pArray;};
	//! returns the safe array, const
	SAFEARRAY* const GetArray() const			{	return m_pArray;};
	//! Handle memory cleaning
	void HandleCleaning( bool bYes )			{	m_bCleaning=bYes;};
	//! return true if memory cleaning is enabled
	bool IsCleaning() const						{	return m_bCleaning;};
	//! Deletes the array if memory cleaning is turned on
	HRESULT CleanArray();

	/*! \brief Attach safe array and returns previous array

	\param pArray new array
	\param bCleaning true if memory handling has to be turned on
	\return previous array if cleaning is disabled, NULL otherwize

	Of course, pArray must be a 1-dimensional array of VT_R4, VT_R8, VT_2 or VT_I4.
	*/
	SAFEARRAY* AttachArray( SAFEARRAY* pArray, bool bCleaning = true);

	/*! \brief Attach safe array and returns previous array

	\param pArray new array
	\param bCleaning true if memory handling has to be turned on
	\return previous array if cleaning is disabled, NULL otherwize

	The acceptable variant types are:
		- VT_ARRAY | VT_R4
		- VT_ARRAY | VT_R8
		- VT_ARRAY | VT_I2
		- VT_ARRAY | VT_I4:

	If the variant is not one of the following, the function will fail.
	*/
	SAFEARRAY* AttachArray( VARIANT v, bool bCleaning = true);
	//@}

protected:
	//! Attributes
	//@{
	//! Safe array
	SAFEARRAY* m_pArray;
	//! Cleaning of array
	bool m_bCleaning;
	// last hresult
	HRESULT m_hr;
	//! var type
	VARTYPE m_vt;
	//@}
};

PGL_DECLARE_SMARTPTR( CPGLSafeArray )

#endif // !defined(AFX_PGLDATATYPES_H__92968E23_E28C_4574_94E3_89CB59FF3F2E__INCLUDED_)
